/*
 * GameUtils.cpp
 *
 *  Created on: May 19, 2012
 *      Author: gonzalo
 */

#include "GameUtils.h"
#include "math.h"
#include "../lib/SDL_rotozoom.h"
#include "SDL/SDL_image.h"
#include "SurfaceUtils.h"

#include "../Constantes.h"

#define MAX_OVERLAPING_RETRIES 1000

void GameUtils::resolveOverlaping(const std::list<WidgetMovimiento*>& elementos,DTOShipStatus* dtoShipStatus,int widht,int height){
	//Check if its overlaping with other
	bool overlaps = true;
	int retries = 0;

	std::list<WidgetMovimiento*> elementosCopy;

	//Start the seed
	srand(time(0));
	dtoShipStatus->posX = getRandIntValueInRange(widht-BASE_DEFAULT_WIDTH*2) + BASE_DEFAULT_WIDTH;
	dtoShipStatus->posY = getRandIntValueInRange(height);

	WidgetMovimiento* evaluating = NULL;
	while(overlaps && retries < MAX_OVERLAPING_RETRIES ){
		overlaps = false;
		//Copy the list
		elementosCopy = elementos;
		while(!elementosCopy.empty()){
			evaluating = *(elementosCopy.begin());

			if (isOverlapping(evaluating,dtoShipStatus)){
				dtoShipStatus->posX = getRandIntValueInRange(widht-BASE_DEFAULT_WIDTH*2) + BASE_DEFAULT_WIDTH;
				dtoShipStatus->posY = getRandIntValueInRange(height);


				overlaps = true;

				std::stringstream stream2;
				stream2 << "NUEVO VALOR TRAS colision !: ";
				stream2 << " X" << dtoShipStatus->posX;
				stream2 << " Y" << dtoShipStatus->posY;
				stream2 << " Retry :" << retries;
				Logger::debug("GameUtils","resolveOverlaping", &stream2);


				//Cut the while
				break;
			}

			std::stringstream stream2;
			elementosCopy.pop_front();
		}
		retries++;
	}

}

int GameUtils::getRandIntValueInRange(int dimension){
	return (rand() % dimension);
}

float GameUtils::getRandFloatValue(){
	return (float)rand()/(float)RAND_MAX;
}

bool GameUtils::isOverlapping(WidgetMovimiento* elemento,DTOShipStatus* dtoShipStatus){

	if(dtoShipStatus == NULL)
		return false;

	SDL_Surface* shipSurfaceAux = SurfaceUtils::loadImage(IMAGES_DEFAULT_FOLDER + dtoShipStatus->imagen	+ IMAGES_DEFAULT_UNPRESSED);
	SDL_Surface* shipSurface= rotozoomSurface(shipSurfaceAux , dtoShipStatus->angle, 1.,SMOOTHING_OFF);
	SDL_FreeSurface(shipSurfaceAux);

	if(shipSurface == NULL)	return false;

	SDL_Rect rectShip;
	rectShip.x = dtoShipStatus->posX - shipSurface->clip_rect.w/2;
	rectShip.y = dtoShipStatus->posY - shipSurface->clip_rect.h/2;
	rectShip.w = shipSurface->clip_rect.w;
	rectShip.h = shipSurface->clip_rect.w;

	bool overlap = GameUtils::overlaps(elemento->getRectangle(),rectShip);

	SDL_FreeSurface(shipSurface);

	return overlap;

}



bool GameUtils::overlaps(SDL_Rect rect1,SDL_Rect rect2){

	bool isSurface1Origen =false;


	if(rect1.x < 0) rect1.x =0;
	if(rect1.y < 0) rect1.y =0;
	if(rect2.x < 0) rect2.x =0;
	if(rect2.y < 0) rect2.y =0;


	int xOrigin = 0;
	int yOrigin = 0;
	//Traslado ambos rectangulos
	//Tomo como cero al que esta mas cerca del origen.

	//Calculo el modulo, para evitar valores negativos
	float mod1 = sqrt(pow(rect1.x,2) + pow(rect1.y,2));
	float mod2 = sqrt(pow(rect2.x,2) + pow(rect2.y,2));

	if(mod2 > mod1  || mod1 == mod2){
		xOrigin = rect1.x;
		yOrigin = rect1.y;
		isSurface1Origen =true;
	}else{
		xOrigin = rect2.x;
		yOrigin = rect2.y;
		isSurface1Origen =false;
	}

	//Muevo ambas superficies al origine
	rect1.x -= xOrigin;
	rect1.y -= yOrigin;

	rect2.x -= xOrigin;
	rect2.y -= yOrigin;


	if(rect1.x < 0) rect1.x =0;
	if(rect1.y < 0) rect1.y =0;
	if(rect2.x < 0) rect2.x =0;
	if(rect2.y < 0) rect2.y =0;


	//Calculo el modulo


	float pos1;
	float pos2;
	if(isSurface1Origen){
		pos1= sqrt(pow(rect1.h,2) + pow(rect1.w,2));
		pos2= sqrt(pow(rect2.x,2) + pow(rect2.y,2));


		if(pos1 > pos2){
			//Hay contacto
			return true;
		}

	}else{
		pos1= sqrt(pow(rect1.x,2) + pow(rect1.y,2));
		pos2= sqrt(pow(rect2.h,2) + pow(rect2.w,2));

		if(pos2 > pos1){
			//Hay contacto
			return true;
		}
	}

	return false;
}


bool GameUtils::compareEquipment (std::pair<Equipment*,Bonus*>* first, std::pair<Equipment*,Bonus*>* second){
	return first->first->getType() < second->first->getType();
}
